#pragma once

#include <iostream>
#include <memory>
#include <functional>
#include <sys/wait.h>

#include "Sock.hpp"

namespace Tcp_module
{
  using namespace Sock_M;
  using namespace Log_Module;
  using namespace Tcp_module;
  using namespace std;
  using tcphander_t = function<bool(SockPtr, InetAddr)>;

  class Tcp_Server
  {
  private:
  bool _is_running;
  int _port;
  tcphander_t _handler;
  shared_ptr<Socket> _sock;
  public:
    Tcp_Server(int port):
        _is_running(false),
        _port(port),
        _handler(nullptr),
        _sock(make_shared<Tcp_Socket>())
    {}
    void init(tcphander_t handler)
    {
      _handler=handler;
      _sock->BulidTcpSock(_port);
    }

    void loop()
    {
      _is_running=true;
      while(_is_running)
      {
        InetAddr client;
        auto sockfd=_sock->Accept(&client);
        if(sockfd==nullptr)
        {
          continue;
        }
        pid_t id=fork();
        if(id==0)
        {
          _sock->close();
          if(fork()>0)
          {
            exit(0);
          }
          _handler(sockfd,client);
          exit(0);
        }
        _sock->close();
        waitpid(id,nullptr,0);
      }
      _is_running=false;
    }
  };

}